package com.dynamic.mybatis.core.generator.method;

import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.dynamic.mybatis.core.generator.MapperMethod;
import com.dynamic.mybatis.core.generator.InjectorMethod;
import com.dynamic.mybatis.core.generator.InjectorHelper;
import com.dynamic.mybatis.core.generator.helper.LogicDeleteHelper;
import com.dynamic.mybatis.core.generator.helper.OptimisticLockInjectorHelper;
import com.dynamic.mybatis.core.generator.helper.UpdateInjectorHelper;
import com.dynamic.mybatis.core.metadata.DynamicMappedStatement;
import com.dynamic.mybatis.core.metadata.MappedStatementMetaField;
import com.dynamic.mybatis.core.metadata.MappedStatementTable;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.apache.ibatis.executor.keygen.NoKeyGenerator;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.scripting.LanguageDriver;
import org.apache.ibatis.session.Configuration;

import java.util.Map;
import java.util.Optional;

/**
 * @Description
 * @Author xs
 * @Date 2023/4/14 10:12
 */
public class UpdateById extends InjectorMethod {
    public UpdateById() {
        super(MapperMethod.StandardMapperMethod.updateById);
    }

    @Override
    public String builderScriptSql(String namespace, MappedStatementTable table, MapperBuilderAssistant assistant) {

        final String additional = OptimisticLockInjectorHelper.optlockVersion(table) + LogicDeleteHelper.getLogicDeleteSql(table, true, true);

        Optional<MappedStatementMetaField> logicDeleteField = InjectorHelper.getLogicDelete(table);
        Optional<MappedStatementMetaField> firstKeyField = InjectorHelper.getFirstKeyField(table);
        String keyColumn = firstKeyField.isPresent() ? firstKeyField.get().getColumn() : null;
        String keyProperty = firstKeyField.isPresent() ? firstKeyField.get().getField() : null;


        String sql = String.format(getSqlTemplate(), table.getTableName(),
                NEWLINE + SPACE + UpdateInjectorHelper.sqlSet(logicDeleteField.isPresent(), false, table, false, null, null) + NEWLINE,
                keyColumn, keyProperty, additional);

        return sql;

    }

    @Override
    public DynamicMappedStatement injectMappedStatement(String namespace, MappedStatementTable table, MapperBuilderAssistant assistant) {
        LanguageDriver languageDriver = assistant.getConfiguration().getDefaultScriptingLanguageInstance();
        Configuration configuration = assistant.getConfiguration();

        Optional<MappedStatementMetaField> firstKeyField = InjectorHelper.getFirstKeyField(table);
        String keyColumn = firstKeyField.isPresent() ? firstKeyField.get().getColumn() : null;
        String keyProperty = firstKeyField.isPresent() ? firstKeyField.get().getField() : null;

        String sql = builderScriptSql(namespace, table, assistant);

        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, Map.class);

        MappedStatement ms = super.addMappedStatement(assistant, table, namespace, sqlSource, SqlCommandType.UPDATE, Map.class, null, Integer.class, NoKeyGenerator.INSTANCE, keyProperty, keyColumn);

        return builderDynamicMappedStatement(namespace, table, ms, sql);
    }
}